package org.dromara.quick.chat.service.impl;

import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.utils.IdGenerator;
import org.dromara.common.model.enums.channel.ChannelTypeEnum;
import org.dromara.common.model.enums.groupuser.GroupInvitationConfirmationEnum;
import org.dromara.common.model.enums.groupuser.GroupMemberPermissionEnum;
import org.dromara.common.model.enums.groupuser.GroupMemberStatusEnum;
import org.dromara.common.redis.utils.RedisUtils;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.constant.CacheConstants;
import org.dromara.quick.chat.domain.ImGroupChat;
import org.dromara.quick.chat.domain.ImGroupMember;
import org.dromara.quick.chat.mapper.ImGroupMemberMapper;
import org.dromara.quick.chat.model.bo.create.AddGroupMemberDTO;
import org.dromara.quick.chat.model.bo.query.ImGroupChatBo;
import org.dromara.quick.chat.model.vo.ImGroupChatVO;
import org.dromara.quick.chat.model.vo.ImGroupMemberVO;
import org.dromara.quick.chat.service.ImChannelUserService;
import org.dromara.quick.chat.service.ImGroupChatService;
import org.dromara.quick.chat.service.ImGroupMemberService;
import org.dromara.quick.chat.service.ImGroupStatisticsService;
import org.dromara.resource.api.RemoteFileService;
import org.dromara.system.api.RemoteUserService;
import org.dromara.system.api.domain.vo.RemoteUserBasicVO;
import org.dromara.utils.HanyuPinyinUtil;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.time.Duration;
import java.util.Date;
import java.util.List;

/**
* @author Stars
* @description 针对表【im_group_member(群成员表，记录群聊中成员的相关信息)】的数据库操作Service实现
* @createDate 2025-03-04 22:33:21
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class ImGroupMemberServiceImpl extends ServiceImpl<ImGroupMemberMapper, ImGroupMember>
    implements ImGroupMemberService{

    private final ImGroupChatService imGroupChatService;
    private final ImChannelUserService imChannelUserService;
    private final ImGroupStatisticsService imGroupStatisticsService;
    private final ImGroupMemberMapper imGroupMemberMapper;
    @DubboReference
    private final RemoteUserService remoteUserService;
    @DubboReference
    private final RemoteFileService remoteFileService;

    @DSTransactional
    @Override
    public R<?> addGroupMember(AddGroupMemberDTO addGroupMemberDTO) {
        log.info("添加群成员,群id为：:{}",addGroupMemberDTO.getGroupId());
        ImGroupChat groupChat = imGroupChatService.getOne(new LambdaQueryWrapper<ImGroupChat>().eq(ImGroupChat::getId, addGroupMemberDTO.getGroupId()));
        if (groupChat == null){
            log.error("群聊不存在,群id为:{}",addGroupMemberDTO.getGroupId());
            return R.fail("群聊不存在");
        }
        Long userId = LoginHelper.getUserId();
        if (super.exists(new LambdaQueryWrapper<ImGroupMember>().eq(ImGroupMember::getMemberId, userId).eq(ImGroupMember::getGroupId, addGroupMemberDTO.getGroupId()))){
            log.info("已加入该群聊,群id为:{}",addGroupMemberDTO.getGroupId());
            return R.fail("已加入该群聊");
        }
        ImGroupMember imGroupMember = new ImGroupMember();
        if (groupChat.getInvitationConfirmation() == GroupInvitationConfirmationEnum.REQUIRED.getCode()){
            imGroupMember.setStatus(GroupMemberStatusEnum.INVITATION_SENT.getCode());
        }else {
            imGroupMember.setStatus(GroupMemberStatusEnum.ACCEPTED.getCode());
        }
        imGroupMember.setId(IdGenerator.getId());
        imGroupMember.setGroupId(addGroupMemberDTO.getGroupId());
        imGroupMember.setMemberId(userId);
        imGroupMember.setMemberPermission(GroupMemberPermissionEnum.REGULAR_MEMBER.getCode());
        imGroupMember.setGroupNote(addGroupMemberDTO.getGroupNote());
        imGroupMember.setInvitationRequestLanguage(addGroupMemberDTO.getInvitationRequestLanguage());
        imGroupMember.setGroupNotePinYin(new HanyuPinyinUtil().toHanyuPinyin(groupChat.getGroupName()));
        imGroupMember.setCreateTime(new Date());
        super.save(imGroupMember);
        log.info("用户: {} 加入群聊: {} 成功", userId, addGroupMemberDTO.getGroupId());

        imGroupStatisticsService.addUserCount(addGroupMemberDTO.getGroupId());
        // 开始往群平道中添加用户信息
        try {
            imChannelUserService.addChannelUser(groupChat.getId().toString(), userId, ChannelTypeEnum.GROUP_CHANNEL);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        // 如果是不需要确认的群，查询群信息返回，移动端直接跳转到聊天框
        if(groupChat.getInvitationConfirmation() == GroupInvitationConfirmationEnum.NOT_REQUIRED.getCode()){
            List<ImGroupChatVO> imGroupChatVOS = imGroupChatService.selectGroupChatList(ImGroupChatBo.builder().groupId(groupChat.getId()).build());
            if (CollectionUtils.isNotEmpty(imGroupChatVOS)) {
                return R.ok(imGroupChatVOS.get(0));
            }
        }

        return R.ok();
    }

    @Override
    public RemoteUserBasicVO handleGroupNicknameAndAvatar(Long groupId,Long userId) {
        RemoteUserBasicVO cacheObject = RedisUtils.getCacheObject(CacheConstants.CACHE_GROUP_NAME_USER_NICKNAME_AVATAR + groupId + userId);
        if (cacheObject != null) {
            return cacheObject;
        }
        RemoteUserBasicVO remoteUserBasicVO = remoteUserService.selectUserBasicById(userId);
        if (remoteUserBasicVO == null) {
            return remoteUserBasicVO;
        }
        // 查询用户昵称
        ImGroupMember imGroupMember = baseMapper.selectOne(new LambdaQueryWrapper<ImGroupMember>()
            .select(ImGroupMember::getGroupNote)
            .eq(groupId != null, ImGroupMember::getGroupId, groupId).eq(userId != null, ImGroupMember::getMemberId, userId));
        if (imGroupMember != null) {
            remoteUserBasicVO.setGroupNote(imGroupMember.getGroupNote());
        }
        // 查询群
        ImGroupChat groupChat = imGroupChatService.getOne(new LambdaQueryWrapper<>(ImGroupChat.class)
            .select(ImGroupChat::getGroupName,ImGroupChat::getGroupAvatar)
            .eq(ImGroupChat::getId, groupId));
        if (groupChat != null) {
            remoteUserBasicVO.setGroupName(groupChat.getGroupName());
            // 查询群头像
            if (StringUtils.isNotBlank(groupChat.getGroupAvatar())) {
                String groupAvatar = remoteFileService.selectUrlByIds(groupChat.getGroupAvatar());
                remoteUserBasicVO.setGroupAvatar(groupAvatar);
            }
        }
        RedisUtils.setCacheObject(CacheConstants.CACHE_GROUP_NAME_USER_NICKNAME_AVATAR + groupId + userId, remoteUserBasicVO, Duration.ofHours(3));
        return remoteUserBasicVO;
    }

    @Override
    public ImGroupMemberVO queryGroupMember(Long groupId, Long userId) {
        ImGroupMemberVO cacheObject = RedisUtils.getCacheObject(CacheConstants.CACHE_IM_GROUP_MEMBER);
        if (cacheObject != null) {
            return cacheObject;
        }
        ImGroupMemberVO imGroupMemberVO = baseMapper.selectVoOne(new LambdaQueryWrapper<ImGroupMember>()
            .eq(groupId != null, ImGroupMember::getGroupId, groupId)
            .eq(userId != null, ImGroupMember::getMemberId, userId), ImGroupMemberVO.class);
        if (imGroupMemberVO != null) {
            RedisUtils.setCacheObject(CacheConstants.CACHE_IM_GROUP_MEMBER, imGroupMemberVO, Duration.ofDays(3));
        }
        return imGroupMemberVO;
    }
}




